import 'package:flutter/material.dart';

/// 缩放组件
class ScaleWidget extends StatefulWidget {
  final Widget child;
  final double? scale;
  final double? scaleX;
  final double? scaleY;
  final double? endScale;
  final double? endScaleX;
  final double? endScaleY;
  final int duration;
  final Curve? curve;
  final Alignment alignment;
  final Offset? origin;
  final bool transformHitTests;
  final FilterQuality? filterQuality;
  final bool animate;

  //循环播放
  final bool repeat;

  // 反向
  final bool reverse;

  const ScaleWidget({
    super.key,
    required this.child,
    this.scale,
    this.scaleX,
    this.scaleY,
    this.endScale,
    this.endScaleX,
    this.endScaleY,
    this.duration = 300,
    this.curve,
    this.alignment = Alignment.center,
    this.origin,
    this.transformHitTests = true,
    this.filterQuality,
    this.animate = false,
    this.repeat = false,
    this.reverse = false,
  });

  @override
  _ScaleWidgetState createState() => _ScaleWidgetState();
}

class _ScaleWidgetState extends State<ScaleWidget> with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<double> _animation;

  // 当前缩放值
  double get _currentScale => widget.endScale == null ? 1 : widget.scale ?? 1.0;

  double get _currentScaleX => widget.endScaleX == null ? 1 : widget.scaleX ?? 1.0;

  double get _currentScaleY => widget.endScaleY == null ? 1 : widget.scaleY ?? 1.0;

  // 目标缩放值
  double get _targetScale => widget.endScale ?? widget.scale ?? 1.0;

  double get _targetScaleX => widget.endScaleX ?? widget.scaleX ?? 1.0;

  double get _targetScaleY => widget.endScaleY ?? widget.scaleY ?? 1.0;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: Duration(milliseconds: widget.duration),
      vsync: this,
    );

    // 创建统一的动画对象
    _animation = Tween<double>(
      begin: 0.0,
      end: 1.0,
    ).animate(widget.curve == null
        ? _controller
        : CurvedAnimation(
            parent: _controller,
            curve: widget.curve!,
          ));

    _start();
  }

  // 当动画可用时启动动画
  void _start() {
    if (widget.animate) {
      if (widget.repeat) {
        _controller.repeat(reverse: widget.reverse);
      } else {
        _controller.forward();
      }
    }
  }

  @override
  void didUpdateWidget(ScaleWidget oldWidget) {
    super.didUpdateWidget(oldWidget);

    // 当动画参数变化时重置动画
    if (widget.animate) {
      if (widget.scale != oldWidget.scale ||
          widget.scaleX != oldWidget.scaleX ||
          widget.scaleY != oldWidget.scaleY ||
          widget.duration != oldWidget.duration ||
          widget.curve != oldWidget.curve ||
          widget.repeat != oldWidget.repeat ||
          widget.reverse != oldWidget.reverse) {
        _controller.duration = Duration(milliseconds: widget.duration);
        _controller.reset();
        _start();
      }
    } else {
      _controller.stop();
    }
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  // 计算动画缩放值
  double get _animatedScale {
    return _currentScale + (_targetScale - _currentScale) * _animation.value;
  }

  double get _animatedScaleX {
    return _currentScaleX + (_targetScaleX - _currentScaleX) * _animation.value;
  }

  double get _animatedScaleY {
    return _currentScaleY + (_targetScaleY - _currentScaleY) * _animation.value;
  }

  @override
  Widget build(BuildContext context) {
    if (widget.animate) {
      return AnimatedBuilder(
        animation: _controller,
        builder: (BuildContext context, Widget? child) {
          return Transform.scale(
            scale: widget.scale != null ? _animatedScale : null,
            scaleX: widget.scale == null ? _animatedScaleX : null,
            scaleY: widget.scale == null ? _animatedScaleY : null,
            alignment: widget.alignment,
            origin: widget.origin,
            transformHitTests: widget.transformHitTests,
            filterQuality: widget.filterQuality,
            child: child,
          );
        },
        child: widget.child,
      );
    } else {
      return Transform.scale(
        scale: widget.scale,
        scaleX: widget.scaleX,
        scaleY: widget.scaleY,
        alignment: widget.alignment,
        origin: widget.origin,
        transformHitTests: widget.transformHitTests,
        filterQuality: widget.filterQuality,
        child: widget.child,
      );
    }
  }
}
